﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;

using RexToy.Logging;
using RexToy.Xml;
using RexToy.L10N;

namespace RexToy.UI.WinForm.Pmlx
{
    static class PmlxUtility
    {
        private static ILog _log = LogContext.GetLogger<IPmlx>();

        private static void ConvertAndSet(IReflector r, string name, object val)
        {
            Type pType = r.GetPropertyType(name);
            r.SetPropertyValue(name, TypeCast.ChangeType(val, pType));
        }

        public static void ApplyValue(this XAccessor x, IReflector r)
        {
            if (!r.ExistProperty(x.LocalName))
            {
                _log.Warning("Object [{0}] don't have property named [{1}]", r.BoundType, x.LocalName);
                return;
            }

            ConvertAndSet(r, x.LocalName, x.GetStringValue());
        }

        public static void ApplyValue(this PmlxNode px, IReflector r)
        {
            if (!r.ExistProperty(px.LocalName))
            {
                _log.Warning("Object [{0}] don't have property named [{1}]", r.BoundType, px.LocalName);
                return;
            }

            object val = null;
            string str = px.Value;
            if (str.BracketedBy(StringPair.Template_Bracket))
            {
                var engine = px.OwnerDocument.ELEngine;
                val = engine.Eval(str.UnBracketing(StringPair.Template_Bracket));
            }
            else
            {
                val = str;
            }

            ConvertAndSet(r, px.LocalName, val);
        }

        public static IStaticResource LoadResourceElement(this PmlxNode node)
        {
            IStaticResource res = (IStaticResource)Activator.CreateInstance(node.MakeType());
            foreach (PmlxNode attr in node.Attributes)
            {
                if (attr.LocalName == PmlxConstant.URI && string.IsNullOrEmpty(attr.Prefix))
                {
                    res.InitializeUri(attr.Value, node.OwnerDocument);
                }
            }

            IReflector r = Reflector.Bind(res);
            foreach (PmlxNode attr in node.Attributes)
            {
                if (attr.LocalName == PmlxConstant.URI && string.IsNullOrEmpty(attr.Prefix))
                    continue;

                attr.ApplyValue(r);
            }

            IResourceContainer rc = res as IResourceContainer;
            if (rc != null)
                rc.ParseContent(node);
            return res;
        }
    }
}
